import Module from "../module/Module"
import Data from "../object/Data"
import Command from "../command/command"
import Message from "../message/message"
import InputEvent from "../event/InputEvent"
type ClassModule = typeof Module | typeof Data | typeof Command | typeof Message | typeof InputEvent
type ClassNew = Module | Data | Command | Message
export default class TypeLookup {
  typeLookupMap: Record<string, ClassModule>
  constructor() {
    this.typeLookupMap = {}
  }
  getKey(e: ClassModule) {
    return "string" == typeof e ? e : e.name
  }
  addType(e: ClassModule) {
    if (!e) throw Error("Cannot index undefined type")
    const t = this.getKey(e)
    if (this.typeLookupMap[t]) throw Error(`Type ${t} already registered`)
    return (this.typeLookupMap[t] = e), t
  }
  getKeyByType(e: ClassModule, forceAdd?: boolean) {
    if (!e) throw Error("Cannot index undefined type")
    const i = this.getKey(e)
    let n = this.typeLookupMap[i]
    !n && forceAdd && ((n = e), this.addType(n))
    return n ? i : ""
  }
  getKeyByInstance(e: ClassNew, forceAdd?: boolean) {
    if (!e) throw Error("Cannot index undefined data")
    const i = e.constructor.name
    let n = this.typeLookupMap[i]
    !n && forceAdd && ((n = e.constructor as ClassModule), this.addType(n))
    return n ? i : ""
  }
  getTypeByKey(e: string) {
    const t = this.typeLookupMap[e]
    if (!t) throw Error("Key not found")
    if ("string" == typeof t) throw Error("non type keyed result not supported")
    return t
  }
  getKnownTypes() {
    return Object.values(this.typeLookupMap)
  }
}
